package com.winchain.chainbill.home.service.impl;

import com.shell.bee.acct.account.po.AcctBkp;
import com.shell.bee.acct.transaction.vo.AcctInfo;
import com.shell.bee.base.utils.DateUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.entity.auth.AuthOrgan;
import com.shell.constant.rel.AssetCode;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.framework.utils.SysDateUtil;
import com.winchain.chainbill.acct.service.MyAcctService;
import com.winchain.chainbill.acct.vo.AcctVo;
import com.winchain.chainbill.basic.activity.service.BasCusCpnService;
import com.winchain.chainbill.basic.activity.vo.BasCusCpnVo;
import com.winchain.chainbill.bill.base.dao.CbDctDatsDao;
import com.winchain.chainbill.bill.biz.query.dao.CbRecQueryDao;
import com.winchain.chainbill.home.service.HomeService;
import com.winchain.chainbill.home.vo.BillIncomeSpendParamVo;
import com.winchain.chainbill.home.vo.BillIncomeSpendTotalVo;
import com.winchain.chainbill.home.vo.BillIncomeTotalVo;
import com.winchain.chainbill.home.vo.BillSpendTotalVo;
import com.winchain.chainbill.home.vo.DailyTxCountResultVo;
import com.winchain.chainbill.home.vo.TxCountParamVo;
import com.winchain.chainbill.home.vo.TxCountResultVo;
import com.winchain.chainbill.trade.service.BillAcctService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("homeService")
public class HomeServiceImpl implements HomeService {
	@Autowired
	CbRecQueryDao cbRecQueryDao;
	@Autowired
	private BillAcctService billAcctService;
	@Autowired
	private MyAcctService myAcctService;
	@Autowired
	private CbDctDatsDao cbDctDatsDao;
	@Autowired
	private BasCusCpnService basCusCpnService;

	public Map<String, Object> getStats() {
		AuthOrgan ent = CommonDataUtil.getCurEnt();
		Map<String, Object> m = new HashMap();
		BigDecimal boldTotal = this.cbRecQueryDao.getHoldBillTotal(ent.getOrganId());
		m.put("holdAmt", boldTotal);

		AcctInfo acctInfo = new AcctInfo();
		acctInfo.setCustId(ent.getOrganId());
		acctInfo.setAcctType("1");
		acctInfo.setCurrCode(AssetCode.XQT.name());
		List<AcctInfo> AcctInfos = this.billAcctService.getAcctInfos(acctInfo);
		BigDecimal availableAmt = new BigDecimal(0);
		BigDecimal totalAmt = new BigDecimal("0");
		if ((AcctInfos != null) && (AcctInfos.size() > 0)) {
			for (AcctInfo acct : AcctInfos) {
				availableAmt = availableAmt.add(acct.getAvailableAmt());
				totalAmt = totalAmt.add(acct.getAcctAmt());
			}
		}
		m.put("availableAmt", availableAmt);
		m.put("totalAmt", totalAmt);

		AcctVo acctVo = this.myAcctService.getSettleAcct();
		m.put("balanceAmt", (null != acctVo) && (null != acctVo.getAcctBkp()) ? acctVo.getAcctBkp().getAcctBlc()
				: Integer.valueOf(0));
		BasCusCpnVo basCusCpnVo = new BasCusCpnVo();
		basCusCpnVo.setCusId(CommonDataUtil.getCurEntId());
		basCusCpnVo.setCpnSts("1");
		Map<String, Object> stats = this.basCusCpnService.getStats(basCusCpnVo);

		m.put("cpnTotalAmt", stats.get("cpn_total_amt"));
		return m;
	}

	public Map<String, Object> queryBillIncomeSpendTotal(BillIncomeSpendParamVo billIncomeSpendParamVo) {
		AuthOrgan ent = CommonDataUtil.getCurEnt();
		String organId = ent.getOrganId();
		billIncomeSpendParamVo.setOrganId(organId);
		Map<String, Object> m = new HashMap();
		BigDecimal incomeTotal = this.cbRecQueryDao.queryBillIncomeTotal(billIncomeSpendParamVo);
		BigDecimal spendTotal = this.cbRecQueryDao.queryBillSpendTotal(billIncomeSpendParamVo);
		List<BillIncomeTotalVo> billIncomeTotalVoList = this.cbRecQueryDao
				.queryBillIncomeTotalList(billIncomeSpendParamVo);
		List<BillSpendTotalVo> billSpendTotalVoList = this.cbRecQueryDao
				.queryBillSpendTotalList(billIncomeSpendParamVo);
		List<BillIncomeSpendTotalVo> billIncomeSpendTotalVoList = new ArrayList();
		List<String> dateList = SysDateUtil.getDateBetween(billIncomeSpendParamVo.getStartTime(),
				billIncomeSpendParamVo.getEndTime());
		for (String dateStr : dateList) {
			BillIncomeSpendTotalVo billIncomeSpendTotalVo = new BillIncomeSpendTotalVo();
			billIncomeSpendTotalVo.setBillTime(DateUtil.parseDate(dateStr, "yyyyMMdd", "yyyy/MM/dd"));
			for (int i = 0; i < billIncomeTotalVoList.size(); i++) {
				String billTime = ((BillIncomeTotalVo) billIncomeTotalVoList.get(i)).getBillTime();
				if (billTime.equals(dateStr)) {
					billIncomeSpendTotalVo
							.setIncomeTotal(((BillIncomeTotalVo) billIncomeTotalVoList.get(i)).getIncomeTotal());
					break;
				}
				billIncomeSpendTotalVo.setIncomeTotal(new BigDecimal(0));
			}
			for (int j = 0; j < billSpendTotalVoList.size(); j++) {
				String billTime = ((BillSpendTotalVo) billSpendTotalVoList.get(j)).getBillTime();
				if (billTime.equals(dateStr)) {
					billIncomeSpendTotalVo
							.setSpendTotal(((BillSpendTotalVo) billSpendTotalVoList.get(j)).getSpendTotal());
					break;
				}
				billIncomeSpendTotalVo.setSpendTotal(new BigDecimal(0));
			}
			billIncomeSpendTotalVoList.add(billIncomeSpendTotalVo);
		}
		m.put("incomeTotal", incomeTotal);
		m.put("spendTotal", spendTotal);
		m.put("rows", billIncomeSpendTotalVoList);
		return m;
	}

	public TxCountResultVo queryTxCountInfo(TxCountParamVo txCountParamVo) throws ParseException {
		txCountParamVo.setFinId(CommonDataUtil.getCurEntId());
		List<DailyTxCountResultVo> list = null;
		BigDecimal totalDayAmt = BigDecimal.ZERO;
		if ("0".equals(txCountParamVo.getTxType())) {
			list = this.cbRecQueryDao.queryDailySendTxInfos(txCountParamVo);
		} else if ("1".equals(txCountParamVo.getTxType())) {
			list = this.cbRecQueryDao.queryDailyXfeTxInfos(txCountParamVo);
		} else if ("2".equals(txCountParamVo.getTxType())) {
			list = this.cbRecQueryDao.queryDailyDctTxInfos(txCountParamVo);
		} else if ("4".equals(txCountParamVo.getTxType())) {
			list = this.cbRecQueryDao.queryDailyRpurTxInfos(txCountParamVo);
		}
		BigDecimal txTotal = new BigDecimal("0");
		int txCount = 0;

		String minDate = txCountParamVo.getStartTime();
		String maxDate = txCountParamVo.getEndTime();
		if (StringUtil.empty(maxDate)) {
			maxDate = DateUtil.getSystemDate();
		}
		if (StringUtil.empty(minDate)) {
			if ((list != null) && (list.size() > 0)) {
				minDate = ((DailyTxCountResultVo) list.get(0)).getTxDate();

				int diffDay = SysDateUtil.getDaysBetween(minDate, maxDate) + 1;
				if (diffDay < 7) {
					minDate = DateUtil.getPreDay(maxDate, -7);
				}
			} else {
				minDate = DateUtil.getPreDay(maxDate, -7);
			}
		}
		List<String> dateList = new ArrayList();
		DailyTxCountResultVo vo;
		for (Iterator localIterator = list.iterator(); localIterator.hasNext();) {
			vo = (DailyTxCountResultVo) localIterator.next();
			BigDecimal bd = new BigDecimal(vo.getDailyTxTotal());
			txTotal = txTotal.add(bd);
			txCount += vo.getDayilTxCount().intValue();
			dateList.add(vo.getTxDate());
			vo.setTxDate(DateUtil.parseDate(vo.getTxDate(), "yyyyMMdd", "yyyy/MM/dd"));
		}
		Object days = SysDateUtil.getDateBetween(minDate, maxDate);
		for (String day : (List<String>) days) {
			if (!dateList.contains(day)) {
				list = fillMissingTxDayData(list, (List) days, dateList, day);
			}
		}
		if (("2".equals(txCountParamVo.getTxType())) && (txTotal.compareTo(BigDecimal.ZERO) > 0)) {
			totalDayAmt = this.cbDctDatsDao.selectTotalAmtByDate(CommonDataUtil.getCurEntId(), minDate, maxDate, null);
			if (totalDayAmt == null) {
				totalDayAmt = BigDecimal.ZERO;
			}
		}
		BigDecimal avgDailyTxTotal = totalDayAmt.divide(new BigDecimal(((List) days).size()), 2,
				RoundingMode.HALF_DOWN);
		TxCountResultVo txCountResultVo = new TxCountResultVo();
		txCountResultVo.setTxTotal(String.valueOf(txTotal));
		txCountResultVo.setTxCount(Integer.valueOf(txCount));
		txCountResultVo.setAvgDailyTxTotal(String.valueOf(avgDailyTxTotal));
		txCountResultVo.setList(list);
		return txCountResultVo;
	}

	public List<DailyTxCountResultVo> fillMissingTxDayData(List<DailyTxCountResultVo> list, List<String> days,
			List<String> dateList, String day) {
		DailyTxCountResultVo dailyTxCountResultVo = new DailyTxCountResultVo();
		dailyTxCountResultVo.setDailyTxTotal("0");
		dailyTxCountResultVo.setDayilTxCount(Integer.valueOf(0));
		dailyTxCountResultVo.setTxDate(DateUtil.parseDate(day, "yyyyMMdd", "yyyy/MM/dd"));
		int index = days.indexOf(day);
		if (index == 0) {
			list.add(0, dailyTxCountResultVo);
			dateList.add(0, day);
		} else {
			String preDay = (String) days.get(days.indexOf(day) - 1);
			int idx = dateList.indexOf(preDay);
			list.add(idx + 1, dailyTxCountResultVo);
			dateList.add(idx + 1, day);
		}
		return list;
	}
}
